#include "cm_filedirectoryitem.h"
using namespace std;
using namespace sqlite3x;

CM_FileDirectoryItem::CM_FileDirectoryItem()
{
}

CM_FileDirectoryItem::~CM_FileDirectoryItem()
{
}

int
CM_FileDirectoryItem::saveFileDirectory(int collectionId, WMI_Result<WMI_FileDirectory>& fileDirectory)
{
	try {
		
		WMI_Directory * parent = fileDirectory.getParent();
		sqlite3_connection con(DEFAULT_DATABASE_NAME.c_str());
		sqlite3_transaction trans(con);
		{
			sqlite3_command cmd(con, INSERT_DIRECTORY_SCRIPT);
			cmd.bind(1, 0); 
			cmd.bind(2, collectionId);
			cmd.bind(3, parent->getCaption());
			cmd.bind(4, parent->getCreationDate().GetTime());
			cmd.bind(5, parent->getDescription());
			cmd.bind(6, parent->getInstallDate().GetTime());
			cmd.bind(7, parent->getLastAccessed().GetTime());
			cmd.bind(8, parent->getLastModified().GetTime());
			cmd.bind(9, parent->getName());
			cmd.bind(10, parent->getStatus());
			cmd.bind(11, parent->isWriteable());
			cmd.executenonquery();
		}
		trans.commit();
		
		int parent_id = 0;
		getDirectoryLastId(parent_id);
		

		if(fileDirectory.getParent()->getFileDirectoryList().size() != 0)
		{
			vector<WMI_FileDirectory*> resulVec = fileDirectory.getObjects()->getFileDirectoryList();
			for(vector<WMI_FileDirectory*>::const_iterator it = resulVec.begin(); it != resulVec.end(); it++ )
			{
				try
				{
					//Verify if is a WMI_Directory
					WMI_Directory * directory;
					directory = dynamic_cast<WMI_Directory*>((*it));
					if (directory != 0)
					{
						saveDirectory(collectionId, directory, parent_id, con);
					}

					//Verify if is a WMI_File
					WMI_File * file;
					file = dynamic_cast<WMI_File*>((*it));
					if(file != 0)
					{
						saveFile( collectionId, file, parent_id, con);
					}
				}
				catch (exception& e) {cout << "Exception: " << e.what();}

			}
		}
		
	}
	catch(exception &ex) {
		cerr << "Exception Occured  in Save DirectoryFile: " << ex.what() << endl;
		return 0;
	}
	return 1;
}

int
CM_FileDirectoryItem::getFileDirectory(int collectionID,  WMI_Result<WMI_FileDirectory>& fileDirectory)
{
	try {

		sqlite3_connection con(DEFAULT_DATABASE_NAME.c_str());
		{
			getDirectories(collectionID, fileDirectory, con);
			getFiles(collectionID, fileDirectory, con);
		}
		con.close();
	}
	catch(exception &ex) {
		cerr << "Exception Occured in Get DirectoryFile: " << ex.what() << endl;
		return 0;
	}
	return 1;
}

int
CM_FileDirectoryItem::getDirectories(int collectionID, WMI_Result<WMI_FileDirectory>& fileDirectory, sqlite3_connection& con)
{
	try
	{

		sqlite3_command cmd(con, SELECT_DIRECTORY_SCRIPT);
		cmd.bind(1, collectionID);

		sqlite3_reader reader=cmd.executereader();

		WMI_Directory * auxDirectory;

		while(reader.read())
		{
			auxDirectory = new WMI_Directory;

			auxDirectory->setCaption(reader.getstring16(3));
			auxDirectory->setCreationDate(CTime(reader.getint64(4)));
			auxDirectory->setDescription(reader.getstring16(5));
			auxDirectory->setInstallDate(CTime(reader.getint64(6)));
			auxDirectory->setLastAccessed(CTime(reader.getint64(7)));
			auxDirectory->setLastModified(CTime(reader.getint64(8)));
			auxDirectory->setName(reader.getstring16(9));
			auxDirectory->setStatus(reader.getstring16(10));
			auxDirectory->setWriteable(reader.getint(11));

			if(reader.getint(1) == 0)
			{
				fileDirectory.setParent(wstring(auxDirectory->getName()));
				fileDirectory.getParent()->setCaption(auxDirectory->getCaption());
				fileDirectory.getParent()->setCreationDate(CTime(auxDirectory->getCreationDate()));
				fileDirectory.getParent()->setDescription(wstring(auxDirectory->getDescription()));
				fileDirectory.getParent()->setInstallDate(CTime(auxDirectory->getInstallDate()));
				fileDirectory.getParent()->setLastAccessed(CTime(auxDirectory->getLastAccessed()));
				fileDirectory.getParent()->setLastModified(CTime(auxDirectory->getLastModified()));
				fileDirectory.getParent()->setName(wstring(auxDirectory->getName()));
				fileDirectory.getParent()->setStatus(wstring(auxDirectory->getStatus()));
				fileDirectory.getParent()->setWriteable(bool(auxDirectory->isWriteable()));
			}
			else
			{
				fileDirectory.getParent()->getFileDirectoryList().push_back(auxDirectory);
			}

		}
	}
	catch(exception &ex) {
	cerr << "Exception Occured in Get Directory: " << ex.what() << endl;
	return 0;
	}
	return 1;
}

int
CM_FileDirectoryItem::getFiles(int collectionID, WMI_Result<WMI_FileDirectory>& fileDirectory, sqlite3_connection& con)
{
	try
	{
		sqlite3_command cmd(con, SELECT_FILE_SCRIPT);
		cmd.bind(1, collectionID);

		sqlite3_reader reader=cmd.executereader();
		WMI_File * auxFile;

		while(reader.read())
		{
			auxFile = new WMI_File;
			auxFile->setCaption(reader.getstring16(3));
			auxFile->setCreationDate(CTime(reader.getint64(4)));
			auxFile->setDescription(reader.getstring16(5));
			auxFile->setInstallDate(CTime(reader.getint64(6)));
			auxFile->setLastAccessed(CTime(reader.getint64(7)));
			auxFile->setLastModified(CTime(reader.getint64(8)));
			auxFile->setName(reader.getstring16(9));
			auxFile->setStatus(reader.getstring16(10));
			auxFile->setWriteable(reader.getint(11));
			
			fileDirectory.getObjects()->getFileDirectoryList().push_back(auxFile);
		}
	}
	catch(exception &ex) {
		cerr << "Exception Occured in Get File: " << ex.what() << endl;
		return 0;
	}
	return 1;
}

int
CM_FileDirectoryItem::saveDirectory(int collectionId, WMI_Directory* dir, int parent_id, sqlite3_connection& con)
{
	try
	{
		 sqlite3_transaction trans(con);
		 {
			 	sqlite3_command cmd(con, INSERT_DIRECTORY_SCRIPT);
				cmd.bind(1, parent_id);
				cmd.bind(2, collectionId);
				cmd.bind(3, dir->getCaption());
				cmd.bind(4, dir->getCreationDate().GetTime());
				cmd.bind(5, dir->getDescription());
				cmd.bind(6, dir->getInstallDate().GetTime());
				cmd.bind(7, dir->getLastAccessed().GetTime());
				cmd.bind(8, dir->getLastModified().GetTime());
				cmd.bind(9, dir->getName());
				cmd.bind(10, dir->getStatus());
				cmd.bind(11, dir->isWriteable());
				cmd.executenonquery();
		
		}
		 trans.commit();
	}
	catch(exception &ex) {
		cerr << "Exception Occured in SaveDirectory: " << ex.what() << endl;
		return 0;
	}
	return 1;
}

int
CM_FileDirectoryItem::saveFile(int collectionID, WMI_File* file, int parent_id, sqlite3_connection& con)
{
	try
	{
		 sqlite3_transaction trans(con);
		 {
				sqlite3_command cmd(con, INSERT_FILE_SCRIPT);
				cmd.bind(1, parent_id);
				cmd.bind(2, collectionID);
				cmd.bind(3, file->getCaption());
				cmd.bind(4, file->getCreationDate().GetTime());
				cmd.bind(5, file->getDescription());
				cmd.bind(6, file->getInstallDate().GetTime());
				cmd.bind(7, file->getLastAccessed().GetTime());
				cmd.bind(8, file->getLastModified().GetTime());
				cmd.bind(9, file->getName());
				cmd.bind(10, file->getStatus());
				cmd.bind(11, file->isWriteable());
				cmd.executenonquery();
		}
		trans.commit();

	}
	catch(exception &ex) {
		cerr << "Exception Occured in SaveFile: " << ex.what() << endl;
		return 0;
	}
	return 1;
}

void 
CM_FileDirectoryItem::getDirectoryLastId(int &res)
{
    try {
		sqlite3_connection con(DEFAULT_DATABASE_NAME.c_str());
        {
            sqlite3_command cmd(con, "select max(directory_id) from directory ");
            sqlite3_reader reader = cmd.executereader();

            if(reader.read()){
                res = reader.getint(0);
            }
        }
        con.close();
		
    }
    catch(exception &ex) {
        cerr << "Exception Occured: fileDirectoryId():" << ex.what() << endl;
        res = 0;
    }

}